package com.xingfly.service;

import com.xingfly.model.Notification;
import com.xingfly.model.jpa.NotifyTypeAndCount;
import com.xingfly.repository.NotificationRepository;
import com.xingfly.util.Type;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 消息提醒服务
 * Created by SuperS on 2016/12/12.
 */
@Service
public class NotificationService {
    private static final String NOTIFY_KEY = "notification:";

    @Autowired
    private NotificationRepository notificationRepository;


    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Resource(name = "redisTemplate")
    private HashOperations<String, String, Integer> hashOps;


    /**
     * 创建提醒
     *
     * @param notification notification对象
     */
    public Notification doNotify(Notification notification) {
        return notificationRepository.save(notification);
    }

    /**
     * 删除提醒
     *
     * @param eventId    事件ID
     * @param notifierId 通告者ID
     * @param notifiedId 被通告者ID
     */
    public void deleteNotify(Long eventId, Long notifierId, Long notifiedId) {
        notificationRepository.deleteByEventIdAndNotifierIdAndNotifiedId(eventId,notifierId,notifiedId);
    }

    /**
     * TODO redis
     * 获取某个用户的Notifications提醒数量
     */
    public Map<String, Integer> getNotificationsCount(Long userId) {
        Map<String, Integer> notifications = new HashMap<>();
        if (!redisTemplate.hasKey(NOTIFY_KEY + userId)) {
            hashOps.putAll(NOTIFY_KEY + userId, getNotificationsMap(notifications, userId));
        } else {
            for (String key : hashOps.keys(NOTIFY_KEY + userId)) {
                notifications.put(key, hashOps.get(NOTIFY_KEY + userId, key));
            }
        }
        return notifications;
    }

    /**
     * 通过UserId查询消息类型和消息数量的个数
     *
     * @param notifications 消息map用来保存信息
     * @param userId        用户ID
     */
    public Map<String, Integer> getNotificationsMap(Map<String, Integer> notifications, Long userId) {
        initNotification(notifications);
        List<NotifyTypeAndCount> list = notificationRepository.findNotificationTypeAndCountByUserId(userId);
        for (NotifyTypeAndCount notifyTypeAndCount : list) {
            notifications.put(Type.toNotifyTypeStr(notifyTypeAndCount.getType()), Math.toIntExact(notifyTypeAndCount.getCount()));
        }
        return notifications;
    }

    /**
     * 初始化Notification
     *
     * @param notifications 提醒map
     */
    private void initNotification(Map<String, Integer> notifications) {
        notifications.put("COMMENT", 0);
        notifications.put("COMMENT_REPLAY", 0);
        notifications.put("FOLLOW", 0);
        notifications.put("LIKE", 0);
        notifications.put("SYSTEM", 0);
    }

    /**
     * 刷新提醒
     *
     * @param userId 用户ID
     */
    public void refreshNotifications(Long userId) {
        Map<String, Integer> notifications = new HashMap<String, Integer>();
        hashOps.putAll(NOTIFY_KEY + userId, getNotificationsMap(notifications, userId));
    }

    /**
     * 获取被通告用户的所有提醒
     *
     * @param userId     被通告用户ID
     * @param notifyType 通知类型
     */
    public List<Notification> getNotifications(Long userId, Integer notifyType) {
        return notificationRepository.findNotificationsByUserIdAndNotifyType(userId, notifyType);
    }


}
